home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
BUSINESS
/
XLMATH22.ZIP
/
SOURCE.ZIP
/
XLAUTO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-02
|
9KB
|
384 lines
/* --------------------------< Include files >--------------------- */
#define WIN31
#define _MSC_VER 800
#include <windows.h>
#include <xlcall.h>
#include <framewrk.h>
#ifdef _XLMATH
#include "XLMATH.H"
#endif
#ifdef _XLMARK
#include "XLMARK.H"
#endif
#ifdef _XLQC
#include <.\xlqc\xlqc.h>
#endif
#include "xlutil.h"
/* -----------------< Forward xlAPI functions >--------------------- */
int __export FAR PASCAL xlAutoOpen(void);
int __export FAR PASCAL xlAutoClose(void);
LPXLOPER __export FAR PASCAL xlAutoRegister(LPXLOPER pxName);
int __export FAR PASCAL xlAutoAdd(void);
int __export FAR PASCAL xlAutoRemove(void);
LPXLOPER __export FAR PASCAL xlAddInManagerInfo(LPXLOPER xAction);
/*----------------------------------------------------------------------*\
General Notes:
Most of these routines are abstracted from the Excel API
Several of the routines require XLL specific names and these
are abstracted from the header files specific to each XLL
\*----------------------------------------------------------------------*/
/* -----------------------<XLL Routines>--------------------------- */
/*
** xlAutoFree
**
** xlAutoFree is called by Excel to allow the DLL to free memory.
** In the DLL, all XLOPER arrays returned to Excel will be freed
** here. By definition, the address of the XLOPER returned to Excel
** is the address of the MULTI structure used to allocate the complete
** array.
*/
void __export FAR PASCAL xlAutoFree(LPXLOPER lpMulti)
{
#ifdef DEBUG
// all calls to xlAutoFree are xltypeMulti
if ((lpMulti->xltype&0xFFF) != xltypeMulti)
debugPrintf("xlAutoFree() - non-Multi type: %u", lpMulti->xltype);
#endif
#ifdef _USE_SMARTHEAP
// always check for a valid pointer
if (MemCheckPtr(gReturnPool, (LPVOID)lpMulti))
{
// and check for good free
if ( !MemFreePtr((LPVOID)lpMulti))
OkMsgBox("xlAutoFree() error freeing valid pointer");
}
else
{
OkMsgBox("xlAutoFree() invalid pointer");
}
FreeMem((LPVOID)lpMulti);
#else
// old-fashioned memory allocation
FreeMem((LPVOID)lpMulti);
_fheapmin();
_nheapmin();
#endif
}
/*
** xlAutoOpen
**
** xlAutoOpen is how Excel loads XLL files.
** The only thing Excel does when the user
** opens an XLL file, is call the xlAutoOpen
** function.
*/
int __export FAR PASCAL xlAutoOpen(void)
{
static XLOPER xDLL, /* The name of this DLL */
xArgs[7], /* The last 7 arguments to REGISTER */
xMenu, // the xltypeMulti containing the menu
xTest, // test if menu exists
FAR *pxMenu, // points to first menu item
FAR *px; // points to the current menu item
int i, j; /* Loop indices */
HANDLE hMenu; // Windows global memory holding menu
/*
** Register all the functions. Functions must
** be registered before you can add a menu.
*/
Excel(xlGetName, &xDLL, 0);
for (i=0; i<rgFuncsRows; i++)
{
for (j=0; j<7; j++)
{
xArgs[j].xltype = xltypeStr;
xArgs[j].val.str = rgFuncs[i][j];
}
Excel(xlfRegister, 0, 8,
(LPXLOPER) &xDLL,
(LPXLOPER) &xArgs[0],
(LPXLOPER) &xArgs[1],
(LPXLOPER) &xArgs[2],
(LPXLOPER) &xArgs[3],
(LPXLOPER) &xArgs[4],
(LPXLOPER) &xArgs[5],
(LPXLOPER) &xArgs[6]);
}
// Create "standalone DLL" menu
Excel(xlfGetBar, &xTest, 3, TempInt(1), TempStr((LPSTR)gspShortLibName),
TempInt(0));
if (xTest.xltype == xltypeErr)
{
// allocate & build menu
px = pxMenu = (LPXLOPER)GlobalLock(hMenu = GlobalAlloc(GMEM_MOVEABLE,
sizeof(XLOPER)*5*rgMenuRows));
for (i=0; i<rgMenuRows; i++)
{
for (j=0; j<5; j++)
{
px->xltype = xltypeStr;
px->val.str = rgMenu[i][j];
px++;
}
}
xMenu.xltype = xltypeMulti;
xMenu.val.array.lparray = pxMenu;
xMenu.val.array.rows = rgMenuRows;
xMenu.val.array.columns = 5;
// does not work unless "Help" found
Excel (xlfAddMenu, &xTest, 3, TempNum(1), (LPXLOPER)&xMenu,
TempStr(" Help"));
if (xTest.xltype == xltypeErr)
{
// then add at end of menu bar
#ifdef DEBUG
debugPrintf("Menu added to end");
#endif
Excel(xlfAddMenu, 0, 2, TempNum(1), (LPXLOPER)&xMenu);
}
GlobalUnlock(hMenu);
GlobalFree(hMenu);
}
Excel(xlFree, 0, 2, (LPXLOPER) &xTest, (LPXLOPER) &xDLL);
return 1;
}
/*
** xlAutoClose
**
*/
int __export FAR PASCAL xlAutoClose(void)
{
int i;
XLOPER x;
/*
** Delete the names added by xlAutoOpen
*/
for (i=0; i<rgFuncsRows; i++)
{
Excel(xlfSetName, 0, 1, TempStr(rgFuncs[i][2]));
}
// Delete the menu
Excel(xlfGetBar, &x, 3, TempInt(1), TempStr((LPSTR)gspShortLibName),
TempInt(0));
if (x.xltype != xltypeErr)
{
Excel(xlfDeleteMenu, 0, 2, TempNum(1), TempStr((LPSTR)gspShortLibName));
Excel(xlFree, 0, 1, (LPXLOPER)&x);
}
return 1;
}
/*
** xlAutoRegister
**
*/
LPXLOPER __export FAR PASCAL xlAutoRegister(LPXLOPER pxName)
{
static XLOPER xDLL, xArgs[7], xRegId;
int i, j;
xRegId.xltype = xltypeErr;
xRegId.val.err = xlerrValue;
for (i=0; i<rgFuncsRows; i++)
{
if (!lpstricmp(rgFuncs[i][0], pxName->val.str))
{
xDLL.xltype = xltypeStr;
xDLL.val.str = (LPSTR)gspShortLibName;
for (j=0; j<7; j++)
{
xArgs[j].xltype = xltypeStr;
xArgs[j].val.str = rgFuncs[i][j];
}
Excel(xlfRegister, &xRegId, 8,
(LPXLOPER) &xDLL,
(LPXLOPER) &xArgs[0],
(LPXLOPER) &xArgs[1],
(LPXLOPER) &xArgs[2],
(LPXLOPER) &xArgs[3],
(LPXLOPER) &xArgs[4],
(LPXLOPER) &xArgs[5],
(LPXLOPER) &xArgs[6]);
return (LPXLOPER) &xRegId;
}
}
return (LPXLOPER) &xRegId;
}
/*
** xlAutoAdd
**
** Called by the Add-In Manager only. When the user
** adds a DLL to the list of active add-ins, the
** Add-In Manager calls xlAutoAdd() and then opens
** the XLL, which in turn calls xlAutoOpen.
**
*/
int __export FAR PASCAL xlAutoAdd(void)
{
static char chBuff[80];
lstrcpy((LPSTR)chBuff, " Thank you for adding ");
lstrcat((LPSTR)chBuff, (LPSTR)gszLibName);
Excel(xlcAlert, 0, 2, TempStr((LPSTR)chBuff),
TempInt(2));
return 1;
}
/*
** xlAutoRemove
**
** Called by the Add-In Manager only. When the
** user removes an XLL from the list of active
** add-ins, the Add-In Manager calls xlAutoRemove()
** and then UNREGISTER("standalone dll").
*/
int __export FAR PASCAL xlAutoRemove(void)
{
static char chBuff[80];
lstrcpy((LPSTR)chBuff, " Thank you for removing ");
lstrcat((LPSTR)chBuff, gszLibName);
Excel(xlcAlert, 0, 2, TempStr((LPSTR)chBuff), TempInt(2));
return 1;
}
/* xlAddInManagerInfo
**
**
** Called by the Add-In Manager to find out some
** things it needs to know about add-ins.
*/
LPXLOPER __export FAR PASCAL xlAddInManagerInfo(LPXLOPER xAction)
{
static XLOPER xInfo, xIntAction;
Excel(xlCoerce, &xIntAction, 2, xAction, TempInt(xltypeInt));
if(xIntAction.val.w == 1)
{
xInfo.xltype = xltypeStr;
xInfo.val.str = (char *)gspLongLibName;
}
else
{
xInfo.xltype = xltypeErr;
xInfo.val.err = xlerrValue;
}
return (LPXLOPER) &xInfo;
}
//
// fExit() - remove standalone DLL functions
//
int FAR PASCAL __export fExit(VOID)
{
XLOPER xDLL, /* The name of this DLL */
xFunc, /* The name of the function */
xRegId; /* The registration ID */
int i;
if ( (MessageBox(NULL, "Do you really want to remove the Add-In tools",
(LPSTR)gszLibName, MB_APPLMODAL|MB_YESNO|MB_ICONQUESTION)) != IDYES)
return 0;
xFunc.xltype = xltypeStr